//
//  QR_Photo.cpp
//  opencv
//
//  Created by 陈铭涛 on 18/11/11.
//  Copyright © 2018年 skakdakd. All rights reserved.
//
#include <opencv2/opencv.hpp>
#include <math.h>
#include <iostream>
using namespace std;
using namespace cv;
const float RATE1_Min = 1.5;
const float RATE1_Max = 3.0;
const float RATE2_Min = 4.0;
const float RATE2_Max = 6.0;

Point hierarchy_center(vector< vector<Point> > contours, int i)
{
    int centerx = 0, centery = 0, n = contours[i].size();
    centerx = (contours[i][n/4].x + contours[i][n*2/4].x + contours[i][3*n/4].x + contours[i][n-1].x)/4;
    centery = (contours[i][n/4].y + contours[i][n*2/4].y + contours[i][3*n/4].y + contours[i][n-1].y)/4;
    Point point = Point(centerx, centery);
    return point;
}

int main(int argc, const char * argv[]) {
    Mat src = imread("/Users/Mittacy/Study/AwakeLion/QR/1.jpeg");
    if (src.empty())
    {
        cout << "can't load image..." << endl;
        return -1;
    }
    Mat src2 = src.clone();
    Mat src_gray;
    Mat src_binary;
    vector< vector<Point> > contours,contours2, contours3;
    vector<Vec4i> hierarchy;
    // 预处理
    cvtColor(src, src_gray, COLOR_BGR2GRAY);
    blur(src_gray, src_gray, Size(3,3));
    threshold(src_gray, src_binary, 100, 255, THRESH_OTSU);
    // 寻找轮廓,采用树结构
    // hierarchy[i][Next, Previous, First_Child, Parent]
    findContours(src_binary, contours, hierarchy,  RETR_TREE, CHAIN_APPROX_NONE, Point(0, 0));
    // 轮廓筛选
    int first_child = 0;
    int parentIdx = -1;
    for(int i = 0; i < contours.size(); i++)
    {
        // hierarchy[i][Next, Previous, First_Child, Parent]
        if (hierarchy[i][2] != -1 && first_child == 0) {
            parentIdx = i;
            first_child++;
            //cout << "第" << i << "个，一if" << endl;
        } else if (hierarchy[i][2] != -1) {
            first_child++;
            //cout << "第" << i << "个，二if" << endl;
        } else if(hierarchy[i][2] == -1) {
            first_child = 0;
            parentIdx = -1;
            //cout << "第" << i << "个，三if" << endl;
        }
        // 找到定位点信息
        if (first_child >= 2)
        {
            double area[3] = {contourArea(contours[parentIdx]), contourArea(contours[parentIdx+1]), contourArea(contours[parentIdx+2])};
            if ( area[0]/area[1] < RATE1_Min || area[0]/area[1] > RATE1_Max ||
                area[1]/area[2] < RATE1_Min || area[1]/area[2] > RATE1_Max ||
                area[0]/area[2] < RATE2_Min || area[0]/area[2] > RATE2_Max )
            {
                continue;
            }
            contours2.push_back(contours[parentIdx]);
            // test
            contours3.push_back(contours[parentIdx]);
            contours3.push_back(contours[parentIdx+1]);
            contours3.push_back(contours[parentIdx+2]);
            //cout << endl << hierarchy[parentIdx] << endl << hierarchy[parentIdx+1] << endl << hierarchy[parentIdx+2] << endl;
            first_child = 0;
            parentIdx = -1;
            cout << "第" << i << "个，找到定位点" << endl;
            cout << "第一个轮廓面积为：" << area[0] << endl;
            cout << "第二个轮廓面积为：" << area[1] << endl;
            cout << "第三个轮廓面积为：" << area[2] << endl;
            cout << "area[0]/area[1] = " << area[0]/area[1] << endl;
            cout << "area[1]/area[2] = " << area[1]/area[2] << endl;
            cout << "area[0]/area[2] = " << area[0]/area[2] << endl;
        }
    }
    if (contours2.size() == 3) {
        // 标记目标轮廓
        for(int i = 0; i < contours3.size(); i++)
            drawContours(src2, contours3, i, CV_RGB(255,0,0), 1);
        // 连接定位点
        Point point[3];
        for(int i = 0; i < contours2.size(); i++)
        {
            point[i] = hierarchy_center(contours2, i);
        }
        line(src2, point[0], point[1], Scalar(0,0,255), 2);
        line(src2, point[1], point[2], Scalar(0,0,255), 2);
        line(src2, point[0], point[2], Scalar(0,0,255), 2);
    }
    imshow("findQR", src2);
    waitKey(0);
    return 0;
}